/*
 * @Author: dogking18 (dogking18@163.com) 
 * @Date: 2022-10-28
 * @Last Modified by: dogking18 (dogking18@163.com) 
 * @Last Modified time: 2025-07-24
 */
class ComponentOption {
    nodeUuids = [];
    comName = "";
};

class InputMatch {
    input = "";
    index = -1;
    origin = "";
};

module.exports = {
    'add-component': function (event, comName) {
        let comOpt = new ComponentOption();
        comOpt.comName = comName;
        if (Editor.Selection.curSelection("node")) {
            Editor.Selection.curSelection("node").forEach(uuid => {
                let node = this.getNodeByUuid(uuid);
                node.addComponent(comName);
                Editor.log(`小可: 添加组件 ${node.name}/${comName}`);
                comOpt.nodeUuids.push(node.uuid);
            });
        }
        Editor.Ipc.sendToPanel('add_component', 'add_component:res-add-component', comOpt);
    },
    'del-component': function (event, comOpt) {
        comOpt.nodeUuids.forEach(uuid => {
            let node = this.getNodeByUuid(uuid);
            let com = node.getComponent(comOpt.comName);
            if (com) {
                com.destroy();
            }
        });
        Editor.Ipc.sendToPanel('add_component', 'add_component:res-del-component', comOpt.comName);
    },
    'copy-component': function (event, comOpt) {
        let err = "";
        for (let i = 0; i < comOpt.nodeUuids.length; i++) {
            let uuid = comOpt.nodeUuids[i];
            let node = this.getNodeByUuid(uuid);
            let com = node.getComponent(comOpt.comName);
            if (com) {
                CopyComponent = {
                    comName: comOpt.comName,
                    enabled: com.enabled,
                };
                try {
                    let keyList = this.getComponentProp(comOpt.comName);
                    keyList.forEach(key => {
                        CopyComponent[key] = com[key];
                    });
                    // const PropertyMap = DEFAULT_LIST[comOpt.comName];
                    // for (let propName in PropertyMap) {
                    //     let propType = PropertyMap[propName];
                    //     CopyComponent[propName] = com[propName];
                    // }
                }
                catch (e) {
                    if (typeof e == "object") {
                        err = JSON.stringify(e);
                    }
                    else {
                        err = e;
                    }
                }
                break;
            }
        }
        Editor.Ipc.sendToPanel('add_component', 'add_component:res-copy-component', JSON.stringify({ comName: comOpt.comName, err: err }));
    },
    'paste-component': function (event, unuse) {
        if (!CopyComponent) {
            Editor.log(`小可: 粘贴失败，没有复制数据。`);
            return;
        }
        let comName = CopyComponent.comName
        let list = Editor.Selection.curSelection("node");
        if (list && list.length > 0) {
            for (let i = 0; i < list.length; i++) {
                let uuid = list[i];
                let node = this.getNodeByUuid(uuid);
                let com = node.addComponent(comName);
                if (!com) {
                    continue;
                }

                let kList = this.getComponentProp(comName);
                kList.forEach(key => {
                    com[key] = CopyComponent[key];
                })
                Editor.log(`小可: 为节点：${node.name}/${comName} 粘贴组件`);
            }
        }
    },
    'paste-component-property': function (event, unuse) {
        if (!CopyComponent) {
            Editor.log(`小可: 粘贴失败，没有复制数据。`);
            return;
        }
        let comName = CopyComponent.comName
        let list = Editor.Selection.curSelection("node");
        if (list && list.length > 0) {
            for (let i = 0; i < list.length; i++) {
                let uuid = list[i];
                let node = this.getNodeByUuid(uuid);
                let com = node.getComponent(comName);
                if (!com) {
                    continue;
                }
                let keyList = this.getComponentProp(comName);
                keyList.forEach(key => {
                    com[key] = CopyComponent[key];
                })
                Editor.log(`小可: 为节点：${node.name}/${comName} 粘贴组件属性 `);
            }
        }
    },
    'del-copy-data': function (event) {
        if (CopyComponent) {
            CopyComponent = null;
        }
        Editor.Ipc.sendToPanel('add_component', 'add_component:res-del-copy-data', null);
    },
    'list-current-components': function (event) {
        let comOptionCol = {};
        if (!Editor.Selection.curSelection("node")) {
            return;
        }
        //找出相同的组件名
        Editor.Selection.curSelection("node").forEach(uuid => {
            let node = this.getNodeByUuid(uuid);
            node._components.forEach(com => {
                let className = cc.js.getClassName(com.constructor);
                let co = comOptionCol[className];
                if (!co) {
                    co = new ComponentOption();
                    co.comName = className;
                    co.comName = cc.js.getClassName(com.constructor);
                    comOptionCol[co.comName] = co;
                }
                co.nodeUuids.push(node.uuid);
            });
        });
        Editor.Ipc.sendToPanel('add_component', 'add_component:res-list-current-components', comOptionCol);

    },
    'input-query': function (event, handle) {
        let comName = handle.comName;
        let matchs = [];
        if (comName.length > 0) {
            for (let key in cc.js._registeredClassNames) {
                if (cc.js.isChildClassOf(cc.js._registeredClassNames[key], cc.Component)) {
                    let res = key.toLowerCase().match(comName.toLowerCase());
                    if (res) {
                        let inputMatch = new InputMatch();
                        inputMatch.input = res[0];
                        inputMatch.origin = key;
                        inputMatch.index = res.index || -1;
                        matchs.push(inputMatch);
                    }
                }
            }
        }
        Editor.Ipc.sendToPanel('add_component', 'add_component:res-input-query', matchs);
    },
    getComponentProp(comName) {
        return cc.js._registeredClassNames[comName].__props__.filter(key => !PROP_EXCEPT_KEYS.find(ele => ele == key));
    },

    getNodeByUuid(uuid) {
        let found = null;
        let _find = (node) => {
            node.children.forEach(child => {
                if (child.uuid == uuid) {
                    found = child;
                    return;
                }
                if (child.children.length > 0) {
                    _find(child);
                }
            });
        };

        _find(cc.director.getScene());
        return found;
    },
    // 'create-node': function (event, param) {
    //   let selected = Editor.Selection.curSelection('node');
    //   if (selected.length > 0) {
    //     param.parentId = selected[0];
    //   }

    //   insertNode(param, (error, node) => {
    //     if (node) {
    //       // select new node
    //       Editor.Selection.select('node', node.uuid);
    //       // Editor.log(`'${node.name}' created`);
    //     }

    //     if (event.reply) {
    //       event.reply(error);
    //     }
    //   });
    // }
};

const PROP_EXCEPT_KEYS = [
    "_name",
    "_objFlags",
    "node",
    "name",
    "uuid",
    "__scriptAsset",
    "_enabled",
    "enabled",
    "enabledInHierarchy",
    "_isOnLoadCalled",
];
//todo: 
var CopyComponent = null;